package udpserver

import (
	"fmt"
	"net"
	"strconv"
	"strings"
)


var UdpDataChan = make(chan []byte, 500)
func Udpserver(udpDatachan chan []byte) {

	//println("=============启动udp服务，从标签接收信息============")
	FileLogs.Info("=============启动udp服务，从标签接收信息============")
	//log.Flush() // 将日志从缓冲区读出，写入到文件
	//defer 	log.Close()
	socket, err := net.ListenUDP("udp4", &net.UDPAddr{
		//IP:   net.IPv4(172, 31, 253, 53),
		IP: net.IPv4(0, 0, 0, 0),
		//IP:   net.IPv4(172, 31, 253, 53),
		Port: 7000,
	})
	if err != nil {
		fmt.Println("listern ", err)
		//udplogs.Debug("listern err:", err)
		return
	}
	defer socket.Close()


	for {
		data := make([]byte, 200)

		_, remoteAddr, err := socket.ReadFromUDP(data)
		if err != nil {
			FileLogs.Info("read data err:", err)
			//udplogs.Debug("read data err:", err)
			continue
		}

		//fmt.Println("收到标签信息，地址是：", remoteAddr)
		FileLogs.Info("收到标签信息，地址是：", remoteAddr)
		//fmt.Println("======缓冲区字符串======：",string(data[:]))
		FileLogs.Info("======缓冲区字符串======：",string(data[:]))
		//ss :=Tool_DecimalByteSlice2HexString(data)

		if string(data[0:9]) == "&&0000000"{//接收到安全帽定位信息
			capinfoarray := strings.Split(string(data[:]), ",")
			FileLogs.Info("切分后的字符数组长度：",strconv.Itoa(len(capinfoarray)))
		    if len(capinfoarray) == 15 {
				Handlecapinfo(string(data[:]))
			}
		}else {//接受到GPS标签定位信息,此处做两件事，一是检测是否是心跳包，如果是心跳包则返回，如果是定位数据包则发送到redis
		
			_, remoteAddr, err := socket.ReadFromUDP(data)
			//println("after")
			if err != nil {
				//fmt.Println("read data err:", err)
				logs.Debug("read data err:", err)
				continue
			}
	
			//fmt.Println("收到标签信息，地址是：", remoteAddr)
			logs.Debug("收到标签信息，地址是：", remoteAddr)
			//fmt.Println(reflect.TypeOf(remoteAddr.IP[0]))
	
			var un1 uint8 = remoteAddr.IP[0]
			//var ip1 int = int(un1)
			var un2 uint8 = remoteAddr.IP[1]
			//var ip2 int = int(un2)
			var un3 uint8 = remoteAddr.IP[2]
			//var ip3 int = int(un3)
			var un4 uint8 = remoteAddr.IP[3]
			//var ip4 int = int(un4)
	
			labelip := strconv.Itoa(int(un1))+"."+strconv.Itoa(int(un2))+"."+strconv.Itoa(int(un3))+"."+strconv.Itoa(int(un4))
			fmt.Println("labelip: ",labelip)
	
	
			//fmt.Println("get data from label ",data)
			//fmt.Println("get data from label",data)
			ss :=Tool_DecimalByteSlice2HexString(data)
			//fmt.Println("消息的十六进制字符串格式为：: ",ss)
			labelid := HexDecc(ss[16:18]+ss[14:16]+ss[12:14]+ss[10:12])
			datalength := HexDecc(ss[6:8]+ss[4:6])
			fmt.Println("labelid: ",labelid)
			fmt.Println("datalength: ",datalength)//数据段长度
			fmt.Println("datatype: ",string(data[10:11]))//数据类型
	
			//如果是标签心跳包，则更新电量信息，并检测是否发送低电量告警
			if ss[8:10] == "15" {
					//fmt.Println("====收到低电量信息====",ss)
	
					//给标签应答
					baghead := "2323"   //包头信息
					bagbody := "000015" //包长+类型
					//fmt.Println(baghead)
					hexlabelid := DecHex(labelid)
					if len(hexlabelid)%2 == 1 {
						hexlabelid = "0" + hexlabelid
					}
					len_hexlabelid := len(hexlabelid)
	
					//补齐8位用户id,改成小端模式
					for i := 0; i < 8-len_hexlabelid; i += 2 {
						hexlabelid = hexlabelid + "00"
					}
					fmt.Println("=====2labelid====:", hexlabelid)
	
					tmp1 := baghead + bagbody + hexlabelid
	
					//十六进制按位异或，忽略包头的两个字节
					tmp2 := Xor(tmp1)
					if len(tmp2) == 1 {
						tmp2 = "0" + tmp2
					}
					fmt.Println("tmp2: ", tmp2)
					tmp3 := tmp1 + tmp2
					fmt.Println("tmp3: ", tmp3)
	
					send_data, _ := hex.DecodeString(tmp3)
					fmt.Println("====send_data:====", send_data)
					fmt.Println(remoteAddr)
	
					socket.WriteToUDP(send_data, remoteAddr)
	
					ss := Tool_DecimalByteSlice2HexString(data[9:10])
					electricquantity := HexDecc(ss)
	
					if electricquantity != 0 {
						//更新电量信息
						_, err := o.Raw("update label_info set electricquantity = ? where labelid = ?", electricquantity, labelid).Exec()
						if err != nil {
							fmt.Println("更新失败！")
						}
					}
	
					if electricquantity < 30 {
						fmt.Println("发送低电量告警")
						udpDatachan <- []byte("elecqand" + strconv.FormatInt(labelid, 10) )
					}
				}else{
					Handlelabelinfo(string(data[:]))
				}
		}
	 }
}